package com.ssy.lingxi.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.ssy.lingxi.common.constant.manage.ShopTypeEnum;
import com.ssy.lingxi.common.constant.template.PageTemplateTypeEnum;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.PageModel;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.platform.manage.api.feign.paas.ShopPAASControllerFeign;
import com.ssy.lingxi.platform.manage.api.model.dto.shop.ShopPAASDTO;
import com.ssy.lingxi.system.common.CommonBooleanEnum;
import com.ssy.lingxi.system.common.ShopConfigPropertyEnum;
import com.ssy.lingxi.system.dao.PageTemplateRepository;
import com.ssy.lingxi.system.dao.ShopConfigRepository;
import com.ssy.lingxi.system.dao.SiteShopRepository;
import com.ssy.lingxi.system.dto.request.CommonIdDTO;
import com.ssy.lingxi.system.entity.PageTemplate;
import com.ssy.lingxi.system.entity.ShopConfig;
import com.ssy.lingxi.system.entity.SiteShop;
import com.ssy.lingxi.system.model.constant.RoleConstant;
import com.ssy.lingxi.system.model.dto.common.CommonStateDTO;
import com.ssy.lingxi.system.model.dto.shop.AddShopDTO;
import com.ssy.lingxi.system.model.dto.shop.SiteIdAndTemplateIdDTO;
import com.ssy.lingxi.system.model.dto.shop.UpdateShopDTO;
import com.ssy.lingxi.system.service.ShopConfigService;
import com.ssy.lingxi.system.utils.UserDetailsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 *  基础设置 - 商城设置 - 业务实现层
 * @author wrc
 * @version 2.0.0
 * @date 2020/7/20
 */
@Slf4j
@Service
public class ShopConfigServiceImpl implements ShopConfigService {

    @Resource
    private UserDetailsUtil userDetailsUtil;
    @Resource
    private ShopConfigRepository shopConfigRepository;
    @Resource
    private PageTemplateRepository pageTemplateRepository;
    @Resource
    private SiteShopRepository siteShopRepository;
    @Resource
    private ShopPAASControllerFeign shopControllerFeign;

    @Override
    public Wrapper<PageData<ShopConfig>> list(PageModel dto) {
        Page<ShopConfig> all = shopConfigRepository.findAll(PageRequest.of(dto.getCurrent(), dto.getPageSize(), Sort.by("id").ascending()));
        return Wrapper.success(new PageData<>(all.getTotalElements(),all.getContent()));
    }

    @Override
    public Wrapper<ShopConfig> details(CommonIdDTO dto) {
        return Wrapper.success(shopConfigRepository.findById(dto.getId()).orElse(null));
    }

    @Override
    @Transactional
    public Wrapper<Void> add(HttpServletRequest request, AddShopDTO dto) {
        //校验
        if(shopConfigRepository.existsByName(dto.getName())) {
            return Wrapper.fail("商城名字已存在请修改后重试。");
        }
        if(!dto.getType().equals(ShopTypeEnum.ENTERPRISE.getCode()) && shopConfigRepository.existsAllByTypeAndEnvironment(dto.getType(), dto.getEnvironment())) {
            return Wrapper.fail("除了企业商城之外，其他商城类型在同一个商城环境下，只能有一个唯一商城。");
        }
        if(dto.getType().equals(ShopTypeEnum.ENTERPRISE.getCode()) && shopConfigRepository.existsAllByTypeAndEnvironmentAndIsDefault(dto.getType(), dto.getEnvironment(),1)&&dto.getIsDefault().equals(1)) {
            return Wrapper.fail("同一个环境下的企业商城只能存在一个默认商城。");
        }

        //如果为企业商城
        if(dto.getType().equals(ShopTypeEnum.ENTERPRISE.getCode())) {
            //校验商城属性
            if(dto.getProperty() == null) {
                return Wrapper.fail("商城类型为企业商城时，商城属性不能为空");
            }
            //同环境同属性的企业商城只能有一个默认商城
            List<ShopConfig> shopConfigList = shopConfigRepository.findByEnvironmentAndTypeAndProperty(
                    dto.getEnvironment(),
                    dto.getType(),
                    dto.getProperty()
            );
            if(dto.getIsDefault().equals(CommonBooleanEnum.YES.getCode()) && CollectionUtil.isNotEmpty(shopConfigList)) {
                shopConfigList = shopConfigList.stream().peek(a -> a.setIsDefault(CommonBooleanEnum.NO.getCode())).collect(Collectors.toList());
                shopConfigRepository.saveAll(shopConfigList);
            }
            if(dto.getIsDefault().equals(CommonBooleanEnum.NO.getCode()) && CollectionUtil.isEmpty(shopConfigList)) {
                dto.setIsDefault(CommonBooleanEnum.YES.getCode());
            }

            //对'是否为自营商城'字段冗余
            dto.setSelf(
                    ShopConfigPropertyEnum.checkSelfShop(dto.getProperty()) ?
                            CommonBooleanEnum.YES.getCode() : CommonBooleanEnum.NO.getCode()
            );
        }

        //新增
        ShopConfig shopConfig = new ShopConfig();
        BeanUtils.copyProperties(dto, shopConfig);
        shopConfig.setCreateRoleId(userDetailsUtil.getLoginUserDetails(request).getId());
        shopConfigRepository.save(shopConfig);

        //调用平台管理服务 -> 新增商城
        ShopPAASDTO shopRequest = new ShopPAASDTO();
        BeanUtils.copyProperties(shopConfig, shopRequest);
        Wrapper<?> wrapper = shopControllerFeign.add(shopRequest);
        if(wrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            log.error("调用平台后台服务失败：{}", wrapper.getMessage());
            throw new BusinessException(ResponseCode.SERVICE_PLATFORM_MANAGE_ERROR);
        }

        return Wrapper.success();
    }

    @Override
    @Transactional
    public Wrapper<Void> update(HttpServletRequest request, UpdateShopDTO dto) {
        //获取商城
        ShopConfig shop = shopConfigRepository.findById(dto.getId()).orElse(null);

        //校验
        if(shop == null){
            return Wrapper.fail("商城信息不存在请检查参数");
        }
        if(shop.getState() != CommonBooleanEnum.NO.getCode()){
            return Wrapper.fail("商城有效状态不能修改");
        }
        if(!shop.getType().equals(dto.getType())) {
            return Wrapper.fail("不能去修改商城类型");
        }
        if(!shop.getEnvironment().equals(dto.getEnvironment())) {
            return Wrapper.fail("不能去修改商城环境");
        }

        //如果为企业商城
        if(dto.getType().equals(ShopTypeEnum.ENTERPRISE.getCode())) {
            //校验商城属性
            if(dto.getProperty() == null) {
                return Wrapper.fail("商城类型为企业商城时，商城属性不能为空");
            }
            if(!shop.getProperty().equals(dto.getProperty())) {
                return Wrapper.fail("不能去修改商城属性");
            }
            List<ShopConfig> shopConfigList = shopConfigRepository.findByEnvironmentAndType(
                    dto.getEnvironment(),
                    dto.getType()
            );
            if(dto.getIsDefault().equals(CommonBooleanEnum.YES.getCode()) && CollectionUtil.isNotEmpty(shopConfigList)) {
                shopConfigList = shopConfigList.stream().peek(a -> a.setIsDefault(CommonBooleanEnum.NO.getCode())).collect(Collectors.toList());
                shopConfigRepository.saveAll(shopConfigList);
            }
            if(dto.getIsDefault().equals(CommonBooleanEnum.NO.getCode()) && CollectionUtil.isEmpty(shopConfigList)) {
                if(shopConfigList.stream().noneMatch(a -> a.getIsDefault().equals(CommonBooleanEnum.YES.getCode()))) {
                    dto.setIsDefault(CommonBooleanEnum.YES.getCode());
                }
            }
        }

        //修改
        shop.setName(dto.getName());
        shop.setUrl(dto.getUrl());
        shop.setLogoUrl(dto.getLogoUrl());
        shop.setDescribe(dto.getDescribe());
        shop.setIsDefault(dto.getIsDefault());
        shop.setMemberOperate(dto.getMemberOperate());
        shop.setUpdateTime(System.currentTimeMillis());
        shop.setCreateRoleId(userDetailsUtil.getLoginUserDetails(request).getId());
        shop.setOpenMro(dto.getOpenMro());
        shopConfigRepository.saveAndFlush(shop);

        //调用平台管理服务 -> 修改商城
        ShopPAASDTO shopRequest = new ShopPAASDTO();
        BeanUtils.copyProperties(shop, shopRequest);
        Wrapper<?> wrapper = shopControllerFeign.update(shopRequest);
        if(wrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            log.error("调用平台后台服务失败：{}", wrapper.getMessage());
            throw new BusinessException(ResponseCode.SERVICE_PLATFORM_MANAGE_ERROR);
        }

        return Wrapper.success();
    }

    @Override
    @Transactional
    public Wrapper<Void> delete(CommonIdDTO dto) {
        //获取商城
        ShopConfig shop = shopConfigRepository.findById(dto.getId()).orElse(null);
        if(shop == null){
            return Wrapper.fail("商城信息不存在请检查参数");
        }
        if(shop.getState() != RoleConstant.State.STATE_INVALID){
            return Wrapper.fail("商城有效状态不能删除");
        }

        //删除商城
        shopConfigRepository.delete(shop);

        //调用平台管理服务 -> 删除商城
        ShopPAASDTO synShopRequest = new ShopPAASDTO();
        synShopRequest.setId(dto.getId());
        Wrapper<?> wrapper = shopControllerFeign.delete(synShopRequest);
        if(wrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            log.error("调用平台后台服务失败：{}", wrapper.getMessage());
            throw new BusinessException(ResponseCode.SERVICE_PLATFORM_MANAGE_ERROR);
        }

        return Wrapper.success();
    }

    @Override
    @Transactional
    public Wrapper<Void> stopAndStart(HttpServletRequest request, CommonStateDTO dto) {
        //获取商城，修改状态
        ShopConfig shop = shopConfigRepository.findById(dto.getId()).orElse(null);
        if(shop == null){
            return Wrapper.fail("商城信息不存在请检查参数");
        }
        shop.setState(dto.getState());
        shop.setUpdateTime(System.currentTimeMillis());
        shop.setCreateRoleId(userDetailsUtil.getLoginUserDetails(request).getId());
        shopConfigRepository.save(shop);

        //调用平台管理服务 -> 停用/启用
        ShopPAASDTO shopRequest = new ShopPAASDTO();
        shopRequest.setId(dto.getId());
        shopRequest.setState(dto.getState());
        Wrapper<?> wrapper = shopControllerFeign.stopAndStart(shopRequest);
        if(wrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            log.error("调用平台后台服务失败：{}", wrapper.getMessage());
            throw new BusinessException(ResponseCode.SERVICE_PLATFORM_MANAGE_ERROR);
        }

        return Wrapper.success();
    }

    @Override
    public Wrapper<List<ShopConfig>> all() {
        List<ShopConfig> shopConfigs = shopConfigRepository.findByState(CommonBooleanEnum.YES.getCode());
        return Wrapper.success(shopConfigs);
    }

    @Override
    public Wrapper<List<ShopConfig>> allBySiteAndTemplate(SiteIdAndTemplateIdDTO dto) {
        //根据模板ID获取模板信息
        PageTemplate pageTemplate = pageTemplateRepository.findById(dto.getTemplateId()).orElse(null);
        if(pageTemplate == null) {
            return Wrapper.fail(ResponseCode.NO_TEMPLATE_FOUND_BASED_ON_ID);
        }

        //根据站点id获取站点和商城中间信息
        List<SiteShop> siteShops = siteShopRepository.findBySiteId(dto.getSiteId());
        if(CollectionUtil.isEmpty(siteShops)) {
            return Wrapper.success(new ArrayList<>());
        }

        //获取商城ID
        List<Long> shopIds = siteShops.stream().map(SiteShop::getShopId).collect(Collectors.toList());

        //获取商城类型
        List<Integer> types;
        if(PageTemplateTypeEnum.checkEnterpriseShopTemplate(pageTemplate.getType())) {
            types = Stream.of(ShopTypeEnum.ENTERPRISE.getCode()).collect(Collectors.toList());
        }else if(pageTemplate.getType().equals(PageTemplateTypeEnum.CHANNEL.getCode())) {
            types = Stream.of(ShopTypeEnum.CHANNEL.getCode(), ShopTypeEnum.CHANNEL_SELF.getCode()).collect(Collectors.toList());
        }else {
            return Wrapper.fail("模板类型不能选择商城");
        }

        //获取是否为自营商城
        int self = CommonBooleanEnum.NO.getCode();
        if(pageTemplate.getType().equals(PageTemplateTypeEnum.SELF.getCode())) {
            self = CommonBooleanEnum.YES.getCode();
        }

        //获取商城
        List<ShopConfig> shopList = shopConfigRepository.findByIdInAndEnvironmentAndStateAndTypeInAndSelf(
                shopIds,
                pageTemplate.getEnvironment(),
                CommonBooleanEnum.YES.getCode(),
                types,
                self
        );

        return Wrapper.success(shopList);
    }
}
